package ch.vd.horario.vaadin;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import ch.vd.horario.vaadin.enums.BusLineEnum;
import ch.vd.horario.vaadin.enums.BusStopEnum;
import ch.vd.horario.vaadin.model.BusStop;
import ch.vd.horario.vaadin.service.BusService;
import ch.vd.horario.vaadin.service.impl.BusServiceImpl;
import ch.vd.horario.vaadin.util.BroswerInfoHelper;

import com.github.wolfie.refresher.Refresher;
import com.github.wolfie.refresher.Refresher.RefreshListener;
import com.vaadin.Application;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

public class BusTimingApplication extends Application implements RefreshListener {

	private static final String DEFAULT_THEME = "standard";

	private static final long serialVersionUID = -4678105567450879937L;

	private BusService busService = BusServiceImpl.getInstance();

	// 30 second
	private static final int SLEEP_TIME_IN_MILLIS = 30000;

	private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

	private List<SingleDataUpdaterThread> threadsToRefresh = new ArrayList<BusTimingApplication.SingleDataUpdaterThread>();

	private TabSheet tabSheet;

	private Tab dateTab;

	@Override
	public void init() {

		final Window mainWindow = new Window("Bustiming Application");
		setMainWindow(mainWindow);

		mainWindow.setWidth("100%");
		((VerticalLayout) mainWindow.getContent()).setMargin(false);
		((VerticalLayout) mainWindow.getContent()).setWidth("100%");

		threadsToRefresh = new ArrayList<BusTimingApplication.SingleDataUpdaterThread>();

		// main layout for Longemall buses
		VerticalLayout mainLongemalle = new VerticalLayout();
		mainLongemalle.setWidth("100%");
		mainLongemalle.setMargin(true);

		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.LONGE_E_32);
		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.LONGE_E_33);
		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.R_VIL_E_7);

		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.LONGE_O_32);
		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.LONGE_O_33);
		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.R_VIL_O_7);

		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.MALEY_R_M1);
		addNewBusStopDetailsPanels(mainLongemalle, BusStopEnum.MALEY_F_M1);
		
		VerticalLayout mainRenens = new VerticalLayout();
		mainRenens.setWidth("100%");
		mainRenens.setMargin(true);
		addNewBusStopDetailsPanels(mainRenens, BusStopEnum.RCFFN_E_7);
		addNewBusStopDetailsPanels(mainRenens, BusStopEnum.RCFFN_E_32);
		addNewBusStopDetailsPanels(mainRenens, BusStopEnum.RCFFS_E_33);
		
		
		// custom personal layout for Eric's buses
		VerticalLayout mainEric = new VerticalLayout();
		mainEric.setMargin(true);
		mainEric.setSizeFull();

		addNewBusStopDetailsPanels(mainEric, BusStopEnum.SALA_Z_65);
		addNewBusStopDetailsPanels(mainEric, BusStopEnum.SAV_O_65);

		BrowserInfoExample browserInfoExample = new BrowserInfoExample();

		ThemeResource busStopIcon = new ThemeResource("../standard/images/bus_stop.png");
		ThemeResource ericIcon = new ThemeResource("../standard/images/eric.png");
		ThemeResource browserIcon = new ThemeResource("../standard/images/computer.png");
		if (BroswerInfoHelper.isIPhone(this)) {
			browserIcon = new ThemeResource("../standard/images/iphone.png");
		} else if (BroswerInfoHelper.isAndroid(this)) {
			browserIcon = new ThemeResource("../standard/images/android.png");
		}

		tabSheet = new TabSheet();
		tabSheet.setSizeFull();

		Panel test = new Panel("new Test");
		String date = sdf.format(new Date());
		dateTab = tabSheet.addTab(test, date, null);
		dateTab.setClosable(false);
		dateTab.setEnabled(false);

		tabSheet.addTab(mainLongemalle, "Longemalle", busStopIcon);
		tabSheet.addTab(mainRenens, "Renens", busStopIcon);
		tabSheet.addTab(mainEric, "Autres", ericIcon);
		tabSheet.addTab(browserInfoExample, "Browser", browserIcon);

		mainWindow.addComponent(tabSheet);

		final Refresher refresher = new Refresher();
		refresher.setRefreshInterval(SLEEP_TIME_IN_MILLIS);
		refresher.addListener(this);
		refresher.setWidth("0px");
		refresher.setHeight("0px");
		mainWindow.addComponent(refresher);

		refresh(null);

		browserInfoExample.init("");

		setTheme(DEFAULT_THEME);

	}

	private void addNewBusStopDetailsPanels(VerticalLayout layout, BusStopEnum busStop) {
		BusStopDetailsPanel panel = new BusStopDetailsPanel();
		panel.addStyleName("padded");
		panel.setWidth("100%");
		panel.setCaption(busStop.getStopInformation());

		layout.addComponent(panel);

		SingleDataUpdaterThread thread = new SingleDataUpdaterThread(busStop, panel);
		threadsToRefresh.add(thread);
	}

	public void refresh(Refresher source) {
		Notification notif = new Notification("Refreshing times ...", Notification.TYPE_TRAY_NOTIFICATION);
		notif.setDelayMsec(1000);

		getMainWindow().showNotification(notif);

		for (SingleDataUpdaterThread thread : threadsToRefresh) {
			thread.run();
		}

		String date = sdf.format(new Date());
		dateTab.setCaption(date);

	}

	class SingleDataUpdaterThread implements Runnable, Serializable {

		private static final long serialVersionUID = -803293415747479320L;

		private final BusStopEnum busStopEnum;
		private final BusLineEnum line;
		private final BusStopDetailsPanel panel;

		public SingleDataUpdaterThread(BusStopEnum busStopEnum, BusStopDetailsPanel panel) {
			super();
			this.line = busStopEnum.getLine();
			this.busStopEnum = busStopEnum;
			this.panel = panel;
		}

		public void run() {

			/**
			 * Refresh stop and times data.
			 */
			try {
				BusStop busStopInformation = busService.getBusStopInformation(line, busStopEnum);

				panel.removeAllComponents();

				List<String> nextTimes = busStopInformation.getNextTimes();
				if (nextTimes.isEmpty()) {
					panel.addComponent(new Label("pas de bus prévus"));
				}

				int j=0;
				for (String time : nextTimes) {
					Label lbl = new Label(time);
					lbl.setWidth("100px");
					panel.addComponent(lbl);
					// ((HorizontalLayout)(panel.getContent())).setComponentAlignment(lbl, Alignment.MIDDLE_CENTER);
					j++;
				}
				
				for (int k = j; k < 5; k++) {
					Label lbl = new Label("-------");
					lbl.setWidth("100px");
					panel.addComponent(lbl);
					// ((HorizontalLayout)(panel.getContent())).setComponentAlignment(lbl, Alignment.MIDDLE_CENTER);
				}
				
			} catch (Exception e) {
				getMainWindow().showNotification("impossible d'updater les horaires ", e.getMessage(),
						Notification.TYPE_ERROR_MESSAGE);
			}

		}
	}

}
